<!DOCTYPE html>
<html lang="en">
    <head>
	<meta name="generator" content="Hugo 0.75.1" />
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="format-detection" content="telephone=no" />

  <title>
    迪克猪的博客
  </title>

  
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
  <link rel="manifest" href="/manifest.json" />
  <meta name="theme-color" content="#ffffff" />

  
  <link
    rel="stylesheet"
    href="https://unpkg.com/modern-normalize@0.6.0/modern-normalize.css"
  />

  
  
  
  
  <link rel="stylesheet" href="https://zsy619.github.io/style.min.f7761d111b74dd5c07f0111decee92938c12abc42e0fd319e1a07483e248b54e.css" integrity="sha256-93YdERt03VwH8BEd7O6Sk4wSq8QuD9MZ4aB0g&#43;JItU4=" />

  
    <link rel="alternate" type="application/rss+xml" href="https://zsy619.github.io/index.xml" title="迪克猪的博客" />
  
  
    
  
</head>

    <body>
        <header id="header">
  <div class="header_container">
    <h1 class="sitetitle">
      <a href="https://zsy619.github.io" title="迪克猪的博客">迪克猪的博客</a>
    </h1>
    <nav class="navbar">
      <ul>
        <li><a href="https://zsy619.github.io">Home</a></li>
        
          <li>
            <a href="/post/">
              
              <span>LINUX性能优化</span>
            </a>
          </li>
        
          <li>
            <a href="/csapp/">
              
              <span>深入理解计算机系统_第三版</span>
            </a>
          </li>
        
          <li>
            <a href="/golang/">
              
              <span>golang</span>
            </a>
          </li>
        
          <li>
            <a href="/docker/">
              
              <span>容器</span>
            </a>
          </li>
        
          <li>
            <a href="/flutter/">
              
              <span>Flutter</span>
            </a>
          </li>
        
          <li>
            <a href="/know/">
              
              <span>知识点</span>
            </a>
          </li>
        
          <li>
            <a href="/categories/">
              
              <span>目录</span>
            </a>
          </li>
        
          <li>
            <a href="/about/">
              
              <span>关于</span>
            </a>
          </li>
        
        <li class="hide-sm"><a href="https://zsy619.github.io/index.xml" type="application/rss+xml">RSS</a></li>
      </ul>
    </nav>
  </div>
</header>

        
<section id="main" class="index">
  <div class="post_list container">
    
    
    <article class="post content">
      <time datetime="2020-06-17T09:25:59&#43;0800" class="date">Wed, Jun 17, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/31%E5%A5%97%E8%B7%AF%E7%AF%87%E7%A3%81%E7%9B%98io%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E7%9A%84%E5%87%A0%E4%B8%AA%E6%80%9D%E8%B7%AF/" title="31|套路篇--磁盘I/O性能优化的几个思路">31|套路篇--磁盘I/O性能优化的几个思路</a>
      </h3>
      <div class="post_content summary">
        I/O 基准测试 I/O 性能优化 应用程序优化  第一，可以用追加写代替随机写，减少寻址开销，加快 I/O 写的速度。 第二，可以借助缓存 I/O ，充分利用系统缓存，降低实际 I/O 的次数。 第三，可以在应用程序内部构建自己的缓存，或者用 Redis 这类外部缓存系统。这样，一方面，能在应用程序内部，控制缓存的数据和生命周期；另一方面，也能降低其他应用程序使用缓存对自身的影响。 第四，在需要频繁读写同一块磁盘空间时，可以用 mmap 代替 read/write，减少内存的拷贝次数。 第五，在需要同步写的场景中，尽量将写请求合并，而不是让每个请求都同步写入磁盘，即可以用 fsync() 取代 O_SYNC。 第六，在多个应用程序共享相同磁盘时，为了保证 I/O 不被某个应用完全占用，推荐你使用 cgroups 的 I/O 子系统，来限制进程 / 进程组的 IOPS 以及吞吐量。 最后，在使用 CFQ 调度器时，可以用 ionice 来调整进程的 I/O 调度优先级，特别是提高核心应用的 I/O 优先级。ionice 支持三个优先级类：Idle、Best-effort 和 Realtime。其中， Best-effort 和 Realtime 还分别支持 0-7 的级别，数值越小，则表示优先级别越高。  文件系统优化  第一，你可以根据实际负载场景的不同，选择最适合的文件系统。比如 Ubuntu 默认使用 ext4 文件系统，而 CentOS 7 默认使用 xfs 文件系统。 第二，在选好文件系统后，还可以进一步优化文件系统的配置选项，包括文件系统的特性（如 ext_attr、dir_index）、日志模式（如 journal、ordered、writeback）、挂载选项（如 noatime）等等。 第三，可以优化文件系统的缓存。 最后，在不需要持久化时，你还可以用内存文件系统 tmpfs，以获得更好的 I/O 性能 。tmpfs 把数据直接保存在内存中，而不是磁盘中。比如 /dev/shm/ ，就是大多数 Linux 默认配置的一个内存文件系统，它的大小默认为总内存的一半。  磁盘优化  第一，最简单有效的优化方法，就是换用性能更好的磁盘，比如用 SSD 替代 HDD。 第二，我们可以使用 RAID ，把多块磁盘组合成一个逻辑磁盘，构成冗余独立磁盘阵列。这样做既可以提高数据的可靠性，又可以提升数据的访问性能。 第三，针对磁盘和应用程序 I/O 模式的特征，我们可以选择最适合的 I/O 调度算法。比方说，SSD 和虚拟机中的磁盘，通常用的是 noop 调度算法。而数据库应用，我更推荐使用 deadline 算法。 第四，我们可以对应用程序的数据，进行磁盘级别的隔离。比如，我们可以为日志、数据库等 I/O 压力比较重的应用，配置单独的磁盘。 第五，在顺序读比较多的场景中，我们可以增大磁盘的预读数据，比如，你可以通过下面两种方法，调整 /dev/sdb 的预读大小。 第六，我们可以优化内核块设备 I/O 的选项。比如，可以调整磁盘队列的长度 /sys/block/sdb/queue/nr_requests，适当增大队列长度，可以提升磁盘的吞吐量（当然也会导致 I/O 延迟增大）。  
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-17T09:17:18&#43;0800" class="date">Wed, Jun 17, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/30%E5%A5%97%E8%B7%AF%E7%AF%87%E5%A6%82%E4%BD%95%E8%BF%85%E9%80%9F%E5%88%86%E6%9E%90%E5%87%BA%E7%B3%BB%E7%BB%9Fio%E7%9A%84%E7%93%B6%E9%A2%88%E5%9C%A8%E5%93%AA%E9%87%8C/" title="30|套路篇--如何迅速分析出系统I/O的瓶颈在哪里？">30|套路篇--如何迅速分析出系统I/O的瓶颈在哪里？</a>
      </h3>
      <div class="post_content summary">
        性能指标 文件系统 I/O 性能指标  首先，最容易想到的是存储空间的使用情况，包括容量、使用量以及剩余空间等。我们通常也称这些为磁盘空间的使用量，因为文件系统的数据最终还是存储在磁盘上。  容易忽略的是索引节点的使用情况，它也包括容量、使用量以及剩余量等三个指标。如果文件系统中存储过多的小文件，就可能碰到索引节点容量已满的问题。   其次，你应该想到的是前面多次提到过的缓存使用情况，包括页缓存、目录项缓存、索引节点缓存以及各个具体文件系统（如 ext4、XFS 等）的缓存。这些缓存会使用速度更快的内存，用来临时存储文件数据或者文件系统的元数据，从而可以减少访问慢速磁盘的次数。  磁盘 I/O 性能指标  使用率，是指磁盘忙处理 I/O 请求的百分比。过高的使用率（比如超过 60%）通常意味着磁盘 I/O 存在性能瓶颈。 IOPS（Input/Output Per Second），是指每秒的 I/O 请求数。 吞吐量，是指每秒的 I/O 请求大小。 响应时间，是指从发出 I/O 请求到收到响应的间隔时间。  性能工具  第一，在文件系统的原理中，我介绍了查看文件系统容量的工具 df。它既可以查看文件系统数据的空间容量，也可以查看索引节点的容量。至于文件系统缓存，我们通过 /proc/meminfo、/proc/slabinfo 以及 slabtop 等各种来源，观察页缓存、目录项缓存、索引节点缓存以及具体文件系统的缓存情况。 第二，在磁盘 I/O 的原理中，我们分别用 iostat 和 pidstat 观察了磁盘和进程的 I/O 情况。它们都是最常用的 I/O 性能分析工具。通过 iostat ，我们可以得到磁盘的 I/O 使用率、吞吐量、响应时间以及 IOPS 等性能指标；而通过 pidstat ，则可以观察到进程的 I/O 吞吐量以及块设备 I/O 的延迟等。 第三，在狂打日志的案例中，我们先用 top 查看系统的 CPU 使用情况，发现 iowait 比较高；然后，又用 iostat 发现了磁盘的 I/O 使用率瓶颈，并用 pidstat 找出了大量 I/O 的进程；最后，通过 strace 和 lsof，我们找出了问题进程正在读写的文件，并最终锁定性能问题的来源——原来是进程在狂打日志。 第四，在磁盘 I/O 延迟的单词热度案例中，我们同样先用 top、iostat ，发现磁盘有 I/O 瓶颈，并用 pidstat 找出了大量 I/O 的进程。可接下来，想要照搬上次操作的我们失败了。在随后的 strace 命令中，我们居然没看到 write 系统调用。于是，我们换了一个思路，用新工具 filetop 和 opensnoop ，从内核中跟踪系统调用，最终找出瓶颈的来源。 最后，在 MySQL 和 Redis 的案例中，同样的思路，我们先用 top、iostat 以及 pidstat ，确定并找出 I/O 性能问题的瓶颈来源，它们正是 mysqld 和 redis-server。随后，我们又用 strace+lsof 找出了它们正在读写的文件。  性能指标和工具的联系  从 I/O 指标出发，你更容易把性能工具同系统工作原理关联起来，对性能问题有宏观的认识和把握。 而从性能工具出发，可以让你更快上手使用工具，迅速找出我们想观察的性能指标。特别是在工具有限的情况下，我们更要充分利用好手头的每一个工具，少量工具也要尽力挖掘出大量信息。   第一个维度，从文件系统和磁盘 I/O 的性能指标出发。换句话说，当你想查看某个性能指标时，要清楚知道，哪些工具可以做到。   第二个维度，从工具出发。也就是当你已经安装了某个工具后，要知道这个工具能提供哪些指标。  如何迅速分析 I/O 的性能瓶颈 想弄清楚性能指标的关联性，就要通晓每种性能指标的工作原理。
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-17T09:04:18&#43;0800" class="date">Wed, Jun 17, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/29%E6%A1%88%E4%BE%8B%E7%AF%87redis%E5%93%8D%E5%BA%94%E4%B8%A5%E9%87%8D%E5%BB%B6%E8%BF%9F%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3/" title="29|案例篇--Redis响应严重延迟，如何解决？">29|案例篇--Redis响应严重延迟，如何解决？</a>
      </h3>
      <div class="post_content summary">
        # -f表示跟踪子进程和子线程，-T表示显示系统调用的时长，-tt表示显示跟踪时间 $ strace -f -T -tt -p 9085 [pid 9085] 14:20:16.
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-17T08:51:46&#43;0800" class="date">Wed, Jun 17, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/28%E6%A1%88%E4%BE%8B%E7%AF%87%E4%B8%80%E4%B8%AAsql%E6%9F%A5%E8%AF%A2%E8%A6%8115%E7%A7%92%E8%BF%99%E6%98%AF%E6%80%8E%E4%B9%88%E5%9B%9E%E4%BA%8B/" title="28|案例篇--一个SQL查询要15秒，这是怎么回事？">28|案例篇--一个SQL查询要15秒，这是怎么回事？</a>
      </h3>
      <div class="post_content summary">
        运行下面的 docker exec 命令，进入 MySQL 的命令行界面：
$ docker exec -i -t mysql mysql .
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-17T08:42:18&#43;0800" class="date">Wed, Jun 17, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/27%E6%A1%88%E4%BE%8B%E7%AF%87%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E7%9A%84%E7%A3%81%E7%9B%98io%E5%BB%B6%E8%BF%9F%E5%BE%88%E9%AB%98/" title="27|案例篇--为什么我的磁盘I/O延迟很高？">27|案例篇--为什么我的磁盘I/O延迟很高？</a>
      </h3>
      <div class="post_content summary">
        用 iostat ，确认是否有 I/O 性能瓶颈。再用 strace 和 lsof ，来定位应用程序以及它正在写入的日志文件路径。最后通过应用程序的接口调整日志级别，完美解决 I/O 问题。  $ top top - 14:27:02 up 10:30, 1 user, load average: 1.
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-17T08:36:15&#43;0800" class="date">Wed, Jun 17, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/26%E6%A1%88%E4%BE%8B%E7%AF%87%E5%A6%82%E4%BD%95%E6%89%BE%E5%87%BA%E7%8B%82%E6%89%93%E6%97%A5%E5%BF%97%E7%9A%84%E5%86%85%E9%AC%BC/" title="26|案例篇--如何找出狂打日志的“内鬼”？">26|案例篇--如何找出狂打日志的“内鬼”？</a>
      </h3>
      <div class="post_content summary">
        文件系统、通用块层以及设备层，就构成了 Linux 的存储 I/O 栈。
  为了优化文件访问的性能，采用页缓存、索引节点缓存、目录项缓存等多种缓存机制，减少对下层块设备的直接调用。
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-11T10:47:19&#43;0800" class="date">Thu, Jun 11, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/25%E5%9F%BA%E7%A1%80%E7%AF%87linux%E7%A3%81%E7%9B%98io%E6%98%AF%E6%80%8E%E4%B9%88%E5%B7%A5%E4%BD%9C%E7%9A%84%E4%B8%8B/" title="25|基础篇--Linux磁盘I/O是怎么工作的（下）">25|基础篇--Linux磁盘I/O是怎么工作的（下）</a>
      </h3>
      <div class="post_content summary">
        磁盘性能指标 使用率、饱和度、IOPS、吞吐量以及响应时间等。这五个指标，是衡量磁盘性能的基本指标。
 使用率，是指磁盘处理 I/O 的时间百分比。过高的使用率（比如超过 80%），通常意味着磁盘 I/O 存在性能瓶颈。 饱和度，是指磁盘处理 I/O 的繁忙程度。过高的饱和度，意味着磁盘存在严重的性能瓶颈。当饱和度为 100% 时，磁盘无法接受新的 I/O 请求。 IOPS（Input/Output Per Second），是指每秒的 I/O 请求数。 吞吐量，是指每秒的 I/O 请求大小。 响应时间，是指 I/O 请求从发出到收到响应的间隔时间。   性能测试工具 fio  磁盘 I/O 观测 iostat 是最常用的磁盘 I/O 性能观测工具，它提供了每个磁盘的使用率、IOPS、吞吐量等各种常见的性能指标，这些指标实际上来自 /proc/diskstats。
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-11T10:29:13&#43;0800" class="date">Thu, Jun 11, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/24%E5%9F%BA%E7%A1%80%E7%AF%87linux%E7%A3%81%E7%9B%98io%E6%98%AF%E6%80%8E%E4%B9%88%E5%B7%A5%E4%BD%9C%E7%9A%84%E4%B8%8A/" title="24|基础篇--Linux磁盘I/O是怎么工作的（上）">24|基础篇--Linux磁盘I/O是怎么工作的（上）</a>
      </h3>
      <div class="post_content summary">
        磁盘 磁盘是可以持久化存储的设备，根据存储介质的不同，常见磁盘可以分为两类：机械磁盘和固态磁盘。
 第一类，机械磁盘，也称为硬盘驱动器（Hard Disk Driver），通常缩写为 HDD。机械磁盘主要由盘片和读写磁头组成，数据就存储在盘片的环状磁道中。在读写数据前，需要移动读写磁头，定位到数据所在的磁道，然后才能访问数据。 第二类，固态磁盘（Solid State Disk），通常缩写为 SSD，由固态电子元器件组成。固态磁盘不需要磁道寻址，所以，不管是连续 I/O，还是随机 I/O 的性能，都比机械磁盘要好得多。  无论机械磁盘，还是固态磁盘，相同磁盘的随机 I/O 都要比连续 I/O 慢很多
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-11T09:56:56&#43;0800" class="date">Thu, Jun 11, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/23%E5%9F%BA%E7%A1%80%E7%AF%87linux%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E6%98%AF%E6%80%8E%E4%B9%88%E5%B7%A5%E4%BD%9C%E7%9A%84/" title="23|基础篇--Linux文件系统是怎么工作的？">23|基础篇--Linux文件系统是怎么工作的？</a>
      </h3>
      <div class="post_content summary">
        索引节点和目录项 Linux 文件系统为每个文件都分配两个数据结构，索引节点（index node）和目录项（directory entry）。它们主要用来记录文件的元信息和目录结构。
 索引节点，简称为 inode，用来记录文件的元数据，比如 inode 编号、文件大小、访问权限、修改日期、数据的位置等。索引节点和文件一一对应，它跟文件内容一样，都会被持久化存储到磁盘中。所以记住，索引节点同样占用磁盘空间。 目录项，简称为 dentry，用来记录文件的名字、索引节点指针以及与其他目录项的关联关系。多个关联的目录项，就构成了文件系统的目录结构。不过，不同于索引节点，目录项是由内核维护的一个内存数据结构，所以通常也被叫做目录项缓存。   索引节点是每个文件的唯一标志，而目录项维护的正是文件系统的树状结构。目录项和索引节点的关系是多对一，可简单理解为，一个文件可以有多个别名。 索引节点和目录项纪录了文件的元数据，以及文件间的目录关系   磁盘读写的最小单位是扇区，然而扇区只有 512B 大小 文件系统又把连续的扇区组成了逻辑块，然后每次都以逻辑块为最小单元，来管理数据。 常见的逻辑块大小为 4KB，也就是由连续的 8 个扇区组成。   第一，目录项本身就是一个内存缓存，而索引节点则是存储在磁盘中的数据。 第二，磁盘在执行文件系统格式化时，会被分成三个存储区域，超级块、索引节点区和数据块区。其中，  超级块，存储整个文件系统的状态。 索引节点区，用来存储索引节点。 数据块区，则用来存储文件数据。    虚拟文件系统 linux文件系统四要素：目录项、索引节点、逻辑块以及超级块
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    <article class="post content">
      <time datetime="2020-06-11T09:33:33&#43;0800" class="date">Thu, Jun 11, 2020</time>
      <h3 class="title">
        <a href="https://zsy619.github.io/post/%E7%AC%AC%E4%B8%89%E5%91%A815-22%E9%98%B6%E6%AE%B5%E5%B0%8F%E7%BB%93/" title="第三周15-22阶段小结">第三周15-22阶段小结</a>
      </h3>
      <div class="post_content summary">
        内存性能 linux内存工作原理  内存映射  内核空间 用户空间 虚拟内存地址 物理内存地址 内存映射 缺页异常   虚拟内存空间分布  内核空间 栈 文件映射 堆 数据段 只读段   内存分配与回收 内存查看工具free  内存buffer与cache  Buffers 是内核缓冲区用到的内存，对应的是 /proc/meminfo 中的 Buffers 值。 Cache 是内核页缓存和 Slab 用到的内存，对应的是 /proc/meminfo 中的 Cached 与 SReclaimable 之和。   proc文件系统  内存泄露  只读段，包括程序的代码和常量，由于是只读的，不会再去分配新的内存，所以也不会产生内存泄漏。 数据段，包括全局变量和静态变量，这些变量在定义时就已经确定了大小，所以也不会产生内存泄漏。 最后一个内存映射段，包括动态链接库和共享内存，其中共享内存由程序动态分配和管理。所以，如果程序在分配后忘了回收，就会导致跟堆内存类似的泄漏问题。  内存泄漏的危害非常大，这些忘记释放的内存，不仅应用程序自己不能访问，系统也不能把它们再次分配给其他应用。内存泄漏不断累积，甚至会耗尽系统内存。
        
          <span class="hellip">&hellip;</span>
        
      </div>
    </article>
    
    


<div class="pagination">
  <ul class="pagination_container">
      
        
          <li class="page-item prev to-left">
            <a href="/page/5/" aria-label="Previous" class="page-link">
              <span aria-hidden="true">❮ Prev</span>
            </a>
          </li>
        
        
          <li class="page-item next to-right">
            <a href="/page/7/" aria-label="Next" class="page-link">
              <span aria-hidden="true">Next ❯</span>
            </a>
          </li>
        
      
  </ul>
</div>


  </div>
</section>

        <a id="back_to_top" title="Go To Top" href="#">
  <span>
    <svg viewBox="0 0 24 24">
      <path fill="none" d="M0 0h24v24H0z"></path>
      <path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71z"></path>
    </svg>
  </span>
</a>

        <footer id="footer">
  <p>
    <span>&copy; 2021 <a href="https://zsy619.github.io" title="迪克猪的博客">迪克猪的博客</a> </span>
    <span>Built with <a rel="nofollow" target="_blank" href="https://gohugo.io">Hugo</a></span>
    <span>Theme by <a rel="nofollow" target="_blank" href="https://github.com/wayjam/hugo-theme-mixedpaper">WayJam</a></span>
  </p>

  <script src="https://zsy619.github.io/js/main.min.8b182175f5874aeed0acc0979345c98d4bde22208ec4f36cc1d6e3102acb4b10.js" integrity="sha256-ixghdfWHSu7QrMCXk0XJjUveIiCOxPNswdbjECrLSxA=" crossorigin="anonymous" async></script>
</footer>

    </body>
</html>
